﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using TFramework.ECS.Group.Manager;

namespace TFramework.ECS.Group.Observable
{
    public struct ObservableGroupToken : IEquatable<ObservableGroupToken>
    {
        public GroupLookup LookupGroup { get; }

        public ObservableGroupToken(int[] withComponents, int[] withoutComponents)
        {
            LookupGroup = new GroupLookup(withComponents, withoutComponents);
        }

        public ObservableGroupToken(GroupLookup lookupGroup)
        {
            LookupGroup = lookupGroup;
        }

        public bool Equals(ObservableGroupToken other)
        {
            bool equal;
            if (other.LookupGroup.RequiredComponents == null)
                equal = LookupGroup.RequiredComponents == other.LookupGroup.RequiredComponents;
            else
                equal = LookupGroup.RequiredComponents?.SequenceEqual(other.LookupGroup.RequiredComponents) ?? LookupGroup.RequiredComponents == other.LookupGroup.RequiredComponents;
            if (other.LookupGroup.ExcludedComponents == null)
                equal = equal && LookupGroup.ExcludedComponents == other.LookupGroup.ExcludedComponents;
            else
                equal = equal && (LookupGroup.ExcludedComponents?.SequenceEqual(other.LookupGroup.ExcludedComponents) ?? LookupGroup.ExcludedComponents == other.LookupGroup.ExcludedComponents);
            return equal;
        }

        public override int GetHashCode()
        {
            var requiredHash = ((IStructuralEquatable)LookupGroup.RequiredComponents)?.GetHashCode(EqualityComparer<int>.Default) ?? 0;
            var excludedHash = ((IStructuralEquatable)LookupGroup.ExcludedComponents)?.GetHashCode(EqualityComparer<int>.Default) ?? 0;
            return requiredHash ^ excludedHash;
        }

    }
}